#pragma once

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"

// 命令类型
typedef enum{
    CMD_GET_INFO = 0x01,                // 获取芯片版本号、USB枚举状态、键盘指示灯状态
    CMD_SEND_KB_GENERAL_DATA = 0x02,    // 发送按键动作
    CMD_SEND_KB_MEDIA_DATA = 0x03,      // 发送多媒体按键数据
    CMD_SEND_MS_ABS_DATA = 0x04,        // 发送绝对鼠标位置数据
    CMD_SEND_MS_REL_DATA = 0x05,        // 发送相对鼠标位置数据
    CMD_SEND_MY_HID_DATA = 0x06,        // 向芯片发送自定义HID数据
    CMD_GET_PARA_CFG = 0x08,            // 获取参数配置
    CMD_SET_PARA_CFG = 0x09,            // 设置参数配置
    CMD_GET_USB_STRING = 0x0A,          // 获取字符串描述配置
    CMD_SET_USB_STRING = 0x0B,          // 设置字符串描述配置
    CMD_SET_DEFAULT_CFG = 0x0C,         // 恢复出厂设置
    CMD_RESET = 0x0F,                   // 复位
    CMD_SEND_MY_HID_DATA2 = 0x10,       // 向芯片发送自定义HID数据（CH9329F扩展命令）
    CMD_GPIO_CONTROL = 0x12,            // GPIO控制命令（CH9329F扩展命令）
    CMD_GET_SP_PARA_CFG = 0x13,         // 获取特殊参数配置信息（CH9329F扩展命令）
    CMD_SET_SP_PARA_CFG = 0x14,         // 设置特殊参数配置信息（CH9329F扩展命令）（掉电不保存）
    CMD_JUMP_TO_IAP = 0x15,             // 进入IAP升级模式（CH9329F扩展命令）
    CMD_SEND_TP_DATA = 0x16,            // 向芯片发送触屏命令（CH9329F扩展命令）

    CMD_READ_INFO = 0x81,               // 回传芯片信息
    CMD_READ_KB_GENERAL_REV = 0x82,     // 回传设置键盘鼠标信息 
    CMD_READ_MY_HID_DATA = 0x87,        // 从芯片读取自定义HID数据
    CMD_READ_MY_HID_DATA2 = 0x91,       // 从芯片读取自定义HID数据（CH9329F扩展命令）
} CMD_ID;

// 命令解析状态
typedef enum{
    REV_WAITE_HEAD1,
    REV_WAITE_HEAD2,
    REV_WAITE_ADDR,
    REV_WAITE_CMD,
    REV_WAITE_LEN,
    REV_WAITE_DATA,
    REV_WAITE_SUM,
} REV_STATUS;

// 键盘状态
typedef struct {
    bool usb_connect;
    bool num_lock;
    bool caps_lock;
    bool scroll_lock;
    bool pc_sleep;
}KB_STATUS;

// 芯片配置
union CFG_PKG{
    struct PARA_CFG_PAK{
        uint8_t chip_mode;              // 芯片工作模式
        uint8_t serial_mode;            // 串口模式
        uint8_t serial_addr;            // 串口地址
        uint32_t serial_baud;           // 串口波特率
        uint16_t reserve;               // 保留位
        uint16_t idle_interrupt_ms;     // 空闲中断时间
        uint16_t vid;
        uint16_t pid;
        uint16_t update_interval;       // 上传时间间隔 
        uint16_t kb_free_delay_ms;      // ascii模式下按键释放间隔
        uint8_t enter_flag;             // ascii模式自动回车标志
        uint64_t enter_sign1;           // ascii模式回车符
        uint32_t kb_filter_begin;       // 键盘过滤开始
        uint32_t kb_filter_end;         // 键盘过滤结束
        uint8_t str_enable;             // 字符串使能标志
        uint8_t fast_update;            // ascii模式快速上传标志
        uint64_t reserve1;
        uint32_t reserve2;
    }__attribute__((packed)) para_cfg; // 芯片配置
    uint8_t para_cfg_buff[50]; 
};

void user_ch9329_init();


void ch9329_reset();                // 芯片软复位
void ch9329_clear_key_status();     // 清空按键状态
void ch9329_get_info();             // 请求芯片信息
void ch9329_get_config();           // 获取芯片配置
void ch9329_set_config();           // 设置芯片配置

/**
 * @brief 设置按键状态
 * 
 * @param hid_num: 按键hid号（仅限常用按键）
 * @param push: true按下  false抬起
*/
void ch9329_update_key_status(uint8_t hid_num, bool push);

void test(uint8_t hid_num);
